package cl.tinet.trainee.ejb;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import cl.tinet.trainee.dao.ProductosDAO;
import cl.tinet.trainee.dao.ProductosDAOImpl;
import cl.tinet.trainee.model.CarroTO;
import cl.tinet.trainee.model.DatosMostrarTO;
import cl.tinet.trainee.model.DetalleCarroTO;
import cl.tinet.trainee.model.ProductoTO;
import cl.tinet.trainee.model.UsuarioTO;

/**
 * Session Bean implementation class CarroBean
 */
@Stateless
public class CarroBean implements CarroBeanLocal {

	private ProductosDAO productosDAO;
	private CarroTO carroTO;
	private DetalleCarroTO detalleCarroTO;	
	private DatosMostrarTO datosMostrarTO;
	
	@PersistenceContext(unitName="conexionCarroCompra")
	private EntityManager em;
		
	@PostConstruct
	public void init(){
		
		inicializarCarro();
		
	}

	/**
	 * {@inheritDoc}
	 */
	public void inicializarCarro(){
				
		carroTO = new CarroTO();
		carroTO.setCompraFinalizada(0);
		carroTO.setNombreUsuario("invitado");
		crearCarro(carroTO);
		
	}
	
	/**
	 * {@inheritDoc}
	 */
	public void crearCarro(CarroTO carroTO){
		productosDAO = new ProductosDAOImpl(em); 
			productosDAO.crearCarro(carroTO);		
	}
	
	/** 
    * {@inheritDoc}
    */
	public List<ProductoTO> listarProductos(int registrosPorPagina, int paginaActual){	  
	  productosDAO = new ProductosDAOImpl(em); 
	  return productosDAO.listarProductos(registrosPorPagina, paginaActual);	  
    }
	
	 /** 
     * {@inheritDoc}
     */
	public List<ProductoTO> listarTodosProductos(){	  
	  productosDAO = new ProductosDAOImpl(em); 
	  return productosDAO.listarTodosProductos();	  
    }
   
    /** 
     * {@inheritDoc}
     */
    public List<DetalleCarroTO> agregarProducto(ProductoTO productoTO){
    	
    	productosDAO = new ProductosDAOImpl(em);
    	carroTO = new CarroTO();
    	carroTO = cargarCarro();
    	List<DetalleCarroTO> lDetalleCarroTO = new ArrayList<DetalleCarroTO>(); 
    	
    	if(verificarProductoEnCarro(carroTO, productoTO)){
    		
    		if(buscarProductoDuplicado(carroTO, productoTO) != null){
    			detalleCarroTO = buscarProductoDuplicado(carroTO, productoTO);	    	   
	    		detalleCarroTO.setCantidad(detalleCarroTO.getCantidad() + 1);
	    		actualizarDetalle(detalleCarroTO);
	    		lDetalleCarroTO.addAll(obtenerDetallesCarro());
    		}
    		
    	}else{
    		
    		detalleCarroTO = new DetalleCarroTO();    
    	    detalleCarroTO.setIdCarro(carroTO);
    	    detalleCarroTO.setIdProducto(productoTO);    		
    		detalleCarroTO.setCantidad(DetalleCarroTO.CANTIDAD_INICIAL);    		
    		
    			lDetalleCarroTO.addAll(carroTO.getlDetalleCarro());
    			lDetalleCarroTO.add(detalleCarroTO);
    			productosDAO.agregarProducto(detalleCarroTO);    	
    	}
    		    	    		    	    	        	    
    	return lDetalleCarroTO;
    }
    
    /**
     * {@inheritDoc}
     */
    public boolean verificarProductoEnCarro(CarroTO carroTO, ProductoTO productoTO){
		
		List<DetalleCarroTO> lDetalleCarroTO = new ArrayList<DetalleCarroTO>(); 
			lDetalleCarroTO.addAll(carroTO.getlDetalleCarro());
			
		for (DetalleCarroTO detalleCarroTO : lDetalleCarroTO) {
			if (detalleCarroTO.getIdProducto().getCodProducto().equals(productoTO.getCodProducto())) {
				return true;
			}
		}	
		
		return false;
	}
    
   /**
    * {@inheritDoc}
    */
    public DetalleCarroTO buscarProductoDuplicado(CarroTO carroTO, ProductoTO productoTO){
    	
    	List<DetalleCarroTO> lDetalleCarroTO = new ArrayList<DetalleCarroTO>(); 
		lDetalleCarroTO.addAll(carroTO.getlDetalleCarro());
		    	
    	for (DetalleCarroTO detalleCarroTO : lDetalleCarroTO) {
			if (detalleCarroTO.getIdProducto().getCodProducto().equals(productoTO.getCodProducto())) {
				return detalleCarroTO;
			}
		}	
    	return null;
    }
    
    /**
     * {@inheritDoc}
     */
    public DatosMostrarTO calcularDatosParaMostrar(List<DetalleCarroTO> lDetalleCarroTO){
    	
    	inicializarInstancias();
    	for (DetalleCarroTO detalleCarroTO : lDetalleCarroTO) {
    		datosMostrarTO.setCantidadProductos(datosMostrarTO.getCantidadProductos() + detalleCarroTO.getCantidad());
    		datosMostrarTO.setTotalCompra(detalleCarroTO.getIdProducto().getPrecio() * datosMostrarTO.getCantidadProductos());
    	}		
    	return datosMostrarTO;
    }
   
    /**
     * {@inheritDoc}  
     */
	public CarroTO cargarCarro() {
		productosDAO = new ProductosDAOImpl(em);
		CarroTO c = productosDAO.cargarCarro();
		c.getlDetalleCarro().size();
		return c;
	}
	   
	/**
	 * {@inheritDoc}
	 */
	public void agregarCantidad(DetalleCarroTO detalleCarroTO){			
		  detalleCarroTO.setCantidad(detalleCarroTO.getCantidad() + 1);
		  actualizarDetalle(detalleCarroTO);			
	}
	
	/**
	 * {@inheritDoc}
	 */
	public CarroTO restarCantidad(DetalleCarroTO detalleCarroTO){				  
		detalleCarroTO.setCantidad(detalleCarroTO.getCantidad() - 1);
		actualizarDetalle(detalleCarroTO);		
		
		return cargarCarro();
	}
		

	/**
	 * {@inheritDoc}
	 */
	public void eliminarDetalle(DetalleCarroTO detalleCarroTO){
		 productosDAO = new ProductosDAOImpl(em); 		  
		 productosDAO.eliminarDetalle(detalleCarroTO);		
	}
	
	
	/**
	 * {@inheritDoc}
	 */
	public void actualizarDetalle(DetalleCarroTO detalleCarroTO){
		 productosDAO = new ProductosDAOImpl(em); 		  
		 productosDAO.actualizarDetalle(detalleCarroTO);
		
	}
	/**
	 * {@inheritDoc}
	 */
	public UsuarioTO identificarUsuario(UsuarioTO usuarioTO){				  
			productosDAO = new ProductosDAOImpl(em);					
			return productosDAO.identificarUsuario(usuarioTO);
				
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean comprar(UsuarioTO usuarioTO){
		productosDAO = new ProductosDAOImpl(em);
		carroTO = cargarCarro();
		carroTO.setCompraFinalizada(1);
		carroTO.setNombreUsuario(usuarioTO.getNombreUsuario());
		carroTO.setFechaCompra(obtenerFechaActual());
		descontarStock(carroTO);
		cargarCarro();
		inicializarCarro();
		return productosDAO.comprar(carroTO);
	}
	
	 /**
     * {@inheritDoc}
     */
	public void descontarStock(CarroTO carroTO) {
		  
		List<DetalleCarroTO> lDetalleCarroTO = new ArrayList<DetalleCarroTO>(); 
			lDetalleCarroTO.addAll(carroTO.getlDetalleCarro());
		List<ProductoTO> lProductoTO = new ArrayList<ProductoTO>();
			lProductoTO.addAll(listarTodosProductos());
			
		for (DetalleCarroTO detalleTO : lDetalleCarroTO) {				
			for (ProductoTO productoTO : lProductoTO) {
				if (detalleTO.getIdProducto().getCodProducto().equals(productoTO.getCodProducto())) {
					productoTO.setStock(productoTO.getStock() - detalleTO.getCantidad());
					actualizarProducto(productoTO);					
				}				
			}
		}			
	}

	/**
	 * {@inheritDoc}
	 */
	public void actualizarProducto(ProductoTO productoTO){
		productosDAO = new ProductosDAOImpl(em);
			productosDAO.actualizarProducto(productoTO);
	}
	/**
	 * {@inheritDoc}
	 */
	public List<DetalleCarroTO> obtenerDetallesCarro(){
		
		List<DetalleCarroTO> lDetalleCarroTO = new ArrayList<DetalleCarroTO>(); 
		lDetalleCarroTO.addAll(cargarCarro().getlDetalleCarro());					
		
		return lDetalleCarroTO;
	}
	
	/**
	 * {@inheritDoc}
	 */
	public boolean registrarUsuario(UsuarioTO usuarioTO){
		productosDAO = new ProductosDAOImpl(em);		
		return productosDAO.registrarUsuario(usuarioTO);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public Date obtenerFechaActual(){		
		Calendar date = Calendar.getInstance();			
		return date.getTime();		
	}
		
	/**
	 * {@inheritDoc}
	 */
	public void inicializarInstancias(){
		datosMostrarTO = new DatosMostrarTO();				
	}
	
	/**
	 * @return the carroTO
	 */
	public CarroTO getCarroTO() {
		return carroTO;
	}

	/**
	 * @param carroTO the carroTO to set
	 */
	public void setCarroTO(CarroTO carroTO) {
		this.carroTO = carroTO;
	}

	/**
	 * @return the productosDAO
	 */
	public ProductosDAO getProductosDAO() {
		return productosDAO;
	}

	/**
	 * @param productosDAO the productosDAO to set
	 */
	public void setProductosDAO(ProductosDAO productosDAO) {
		this.productosDAO = productosDAO;
	}

	/**
	 * @return the detalleCarroTO
	 */
	public DetalleCarroTO getDetalleCarroTO() {
		return detalleCarroTO;
	}

	/**
	 * @param detalleCarroTO the detalleCarroTO to set
	 */
	public void setDetalleCarroTO(DetalleCarroTO detalleCarroTO) {
		this.detalleCarroTO = detalleCarroTO;
	}

	/**
	 * @return the em
	 */
	public EntityManager getEm() {
		return em;
	}

	/**
	 * @param em the em to set
	 */
	public void setEm(EntityManager em) {
		this.em = em;
	}

	/**
	 * @return the datosMostrarTO
	 */
	public DatosMostrarTO getDatosMostrarTO() {
		return datosMostrarTO;
	}

	/**
	 * @param datosMostrarTO the datosMostrarTO to set
	 */
	public void setDatosMostrarTO(DatosMostrarTO datosMostrarTO) {
		this.datosMostrarTO = datosMostrarTO;
	}    
}
